package webserver;

import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.PrettyHtmlSerializer;
import org.htmlcleaner.TagInfo;
import org.htmlcleaner.TagNode;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Tag;
import org.jsoup.select.Elements;

public class JSPMaker {
    public static void main(String[] args) {
        String sourceDirectory = "Resources/config/ui";
        String outputDirectory = "output/ui";

        try {
            convertHtmlToJsp(sourceDirectory, outputDirectory);
            System.out.println("Conversion completed successfully.");
        } catch (IOException e) {
            System.out.println("Error occurred during conversion: " + e.getMessage());
        }
    }

    private static void convertHtmlToJsp(String sourceDirectory, String outputDirectory) throws IOException {
        File sourceDir = new File(sourceDirectory);
        File outputDir = new File(outputDirectory);

        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        if (sourceDir.isDirectory()) {
            File[] files = sourceDir.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    String subOutputDirectory = outputDirectory + "/" + file.getName();
                    convertHtmlToJsp(file.getAbsolutePath(), subOutputDirectory);
                } else if (file.isFile() && file.getName().endsWith(".html")) {
                    String jspFileName = file.getName().replace(".html", ".jsp");
                    File outputFile = new File(outputDirectory + "/" + jspFileName);
                    String content = FileUtils.readFileToString(file, "UTF-8");
                    content = convert(content);
                    FileUtils.writeStringToFile(outputFile, content, "UTF-8");
                }
            }
        }
    }

    static String dependence =
            "<%@ page import=\"app.AppRemoteConnector\" %>\n" +
            "<%@ page import=\"com.alibaba.fastjson.JSONArray\" %>\n" +
            "<%@ page import=\"com.alibaba.fastjson.JSON\" %>\n" +
            "<%@ page import=\"java.util.Map\" %>\n" +
            "<%@ page import=\"java.util.HashMap\" %>\n" +
            "<%@ page import=\"java.util.LinkedHashMap\" %>\n" +
            "<%@ page import=\"webserver.HTMLMaker\" %>\n" +
            "<%@ page contentType=\"text/html;charset=UTF-8\" language=\"java\" %>\n";

    static String declaration =
            "<jsp:scriptlet>\n" +
            "    AppRemoteConnector conn = (AppRemoteConnector) application.getAttribute(\"conn\");\n" +
            "    HTMLMaker maker = (HTMLMaker) application.getAttribute(\"maker\");\n" +
            "</jsp:scriptlet>\n";

    static String style =
            "<style>\n" +
            ".ON {background-color:green;}\n" +
            ".OFF {background-color:red;}\n" +
            ".beautiful-table table {border-collapse:collapse;}\n" +
            ".beautiful-table th {background-color: #c9c9c9;text-align:left;padding:8px;}\n" +
            ".beautiful-table tr:nth-child(even) {background-color:#f1f3f3;}\n" +
            ".beautiful-table td, .beautiful-table th {border: 1px solid #bbbbbb;padding:4px 8px 4px 8px;}\n" +
            "</style>\n";

    private static String convert(String html) {
        Document doc = Jsoup.parse(html);
        Elements platformElements = doc.select("platform-table, platform-h1");
        for (Element element : platformElements) {
            StringBuilder replaceStr = new StringBuilder("<jsp:expression>");
            switch (element.tagName()) {
                case "platform-table":
                    String header = replace(element.attributes().get("header"));
                    String data = replace(element.attributes().get("data"));
                    replaceStr.append("maker.makeTable(").append(header).append(", ").append(data).append(")");
                    break;
            }
            replaceStr.append("</jsp:expression>");
            element.replaceWith(Jsoup.parse(replaceStr.toString()).body().child(0));
        }
        String newHtml = doc.html();
        Pattern pattern = Pattern.compile("\\$\\{[^}]+}");
        Matcher matcher = pattern.matcher(newHtml);
        while (matcher.find()) {
            String originalString = matcher.group();
            String replaceString = "<jsp:expression>" + replace(originalString) + "</jsp:expression>";
            newHtml = newHtml.replace(originalString, replaceString);
        }
        doc = Jsoup.parse(newHtml);
        Element htmlElement = doc.selectFirst("html");
        if (htmlElement == null) {
            doc = Jsoup.parse("<html>" + newHtml + "</html>");
            htmlElement = doc.selectFirst("html");
        }
        Element head = doc.selectFirst("head");
        if (head != null) {
            head.prepend("<head>" + style + "</head>");
        } else {
            head = htmlElement.prependElement("head");
            head.prepend(style);
        }
        Element body = doc.selectFirst("body");
        if (body != null) {
            body.prepend(declaration);
        } else {
            body = new Element(Tag.valueOf("body"), "");
            Elements htmlChildren = htmlElement.children();
            for (Element htmlChild : htmlChildren) {
                if (htmlChild.tagName().equals("head")) {
                    continue;
                }
                body.appendChild(htmlChild);
                htmlChild.remove();
            }
            body.prepend(declaration);
            htmlElement.append(body.html());
        }
        return dependence + doc.html();
    }

    //匹配${}的正则表达式
    static String regex = "\\$\\{[^}]+}";
    public static String replace(String originalString) {
        StringBuilder sb = new StringBuilder();
        if (!originalString.contains("${")) {
            sb.append("\"").append(originalString.replaceAll("\"", "\\\\\"")).append("\"");
        } else {
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(originalString);

            int lastEnd = 0;
            while (matcher.find()) {
                if (lastEnd != 0) {
                    sb.append("\"").append(originalString, lastEnd, matcher.start()).append("\" + ");
                }
                sb.append("conn.raw(\"")
                        .append(matcher.group().substring(1).replaceAll("\"", "\\\\\""))
                        .append("\")");
                sb.append(" + ");
                lastEnd = matcher.end();
            }
            if (lastEnd < originalString.length()) {
                sb.append("\"").append(originalString.substring(lastEnd)).append("\"");
            } else {
                sb.delete(sb.length() - 3, sb.length());
            }
        }

        return sb.toString();
    }
}
